package xxxx.com.dao.base;

import org.apache.commons.dbutils.BasicRowProcessor;
import org.apache.commons.dbutils.GenerousBeanProcessor;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.RowProcessor;
import org.apache.commons.dbutils.handlers.BeanHandler;
import xxxx.com.annotation.Table;
import xxxx.com.utils.JDBCUtil;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class BaseDao<T> {

    public int adu(String sql,Object[] obj){
        QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());
        int flag = 0;
        try {
            flag = qr.update(sql,obj);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return flag;
    }

    public T get(Object id, Class<T> aClass) {
        //第一步 通过反射，拿到注解
        Table table = aClass.getDeclaredAnnotation(Table.class);
        String tableName = null;
        if (null != table) {
            //注解里面的值 就是表名
            tableName = table.value();
        }
        String sql = "select * from " + tableName + " where id = ?";
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        T obj = null;
        try {
            connection = JDBCUtil.getConnection();
            statement = connection.prepareStatement(sql);
            statement.setObject(1, id);
            resultSet = statement.executeQuery();
            if (resultSet.next()) {
                obj = aClass.newInstance();// Student student = new Student();
                //后面都是用反射去获取Student的字段
                Field[] fields = aClass.getDeclaredFields();
                for (Field field : fields) {
                    String fieldName = field.getName();
                    String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
                    //通过反射 获取set的方法
                    Method method = aClass.getDeclaredMethod(methodName, field.getType());
                    //通过反射 代理执行 本质上就等同于 student.setXXX(resultSet.getObject("XXX"));
                    method.invoke(obj, resultSet.getObject(fieldName));
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.close(null, statement, connection);
        }
        return obj;
    }

//    public List<T> findAll(Class<T> aClass) {
//        //第一步 通过反射，拿到注解
//        Table table = aClass.getDeclaredAnnotation(Table.class);
//        String tableName = null;
//        if (null != table) {
//            //注解里面的值 就是表名
//            tableName = table.value();
//        }
//        List<T> list = new ArrayList<>();
//        if (null != tableName) {
//            String sql = " select * from " + tableName;
//            Connection connection = null;//数据库链接
//            PreparedStatement statement = null;//sql预处理执行
//            ResultSet resultSet = null;//sql执行完毕后返回的结果集
//            //原生的JDBC
//            try {
//                //获取数据库链接
//                connection = JDBCUtil.getConnection();
//                statement = connection.prepareStatement(sql);
//                resultSet = statement.executeQuery();
//                while (resultSet.next()) {
//                    //游标遍历数据库查处的一条条记录
//                    Object obj = aClass.newInstance();// Student student = new Student();
//                    //当遍历到第一条记录，后面都是用反射去获取Student的字段
//                    Field[] fields = aClass.getDeclaredFields();
//                    for (Field field : fields) {
//                        String fieldName = field.getName();
//                        String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
//                        //通过反射 获取set的方法
//                        Method method = aClass.getDeclaredMethod(methodName, field.getType());
//                        //通过反射 代理执行 本质上就等同于 student.setXXX(resultSet.getObject("XXX"));
//                        method.invoke(obj, resultSet.getObject(fieldName));
//                    }
//                    // list.add(student)
//                    list.add((T) obj);
//                }
//
//            } catch (Exception e) {
//                e.printStackTrace();
//            } finally {
//                JDBCUtil.close(resultSet, statement, connection);
//            }
//        }
//
//        return list;
//    }
//
//    public void add(T t) {
//        Class<?> aClass = t.getClass();
//        //第一步 通过反射，拿到注解
//        Table table = aClass.getDeclaredAnnotation(Table.class);
//        String tableName = null;
//        if (null != table) {
//            //注解里面的值 就是表名
//            tableName = table.value();
//        }
//        Field[] fields = aClass.getDeclaredFields();
//        StringBuilder sql = new StringBuilder();
//        sql.append("insert into ").append(tableName).append(" values(");
//        for (int i = 1; i <= fields.length; i++) {
//            if (i == fields.length) {
//                sql.append("?").append(")");
//            } else {
//                sql.append("?").append(",");
//            }
//        }
//
//
//        Connection connection = null;//数据库链接
//        PreparedStatement statement = null;//sql预处理执行
//        try {
//            connection = JDBCUtil.getConnection();
//            statement = connection.prepareStatement(sql.toString());
//            int index = 1;
//            for (Field field : fields) {
//                String fieldName = field.getName();
//                String methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
//                //通过反射 获取get的方法
//                Method method = aClass.getDeclaredMethod(methodName);
//                //通过反射 代理执行
//                Object invoke = method.invoke(t);
//                statement.setObject(index, invoke);
//                index++;
//            }
//            statement.execute();
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            JDBCUtil.close(null, statement, connection);
//        }
//
//    }
//
//    public void del(Object id, Class<T> aClass) {
//        //第一步 通过反射，拿到注解
//        Table table = aClass.getDeclaredAnnotation(Table.class);
//        String tableName = null;
//        if (null != table) {
//            //注解里面的值 就是表名
//            tableName = table.value();
//        }
//        String sql = "delete from " + tableName + " where id = ?";
//        Connection connection = null;
//        PreparedStatement statement = null;
//        try {
//            connection = JDBCUtil.getConnection();
//            statement = connection.prepareStatement(sql);
//            statement.setObject(1, id);
//            statement.execute();
//        } catch (SQLException e) {
//            e.printStackTrace();
//        } finally {
//            JDBCUtil.close(null, statement, connection);
//        }
//    }
//
//    public T get(Object id, Class<T> aClass) {
//        //第一步 通过反射，拿到注解
//        Table table = aClass.getDeclaredAnnotation(Table.class);
//        String tableName = null;
//        if (null != table) {
//            //注解里面的值 就是表名
//            tableName = table.value();
//        }
//        String sql = "select * from " + tableName + " where id = ?";
//        Connection connection = null;
//        PreparedStatement statement = null;
//        ResultSet resultSet = null;
//        T obj = null;
//        try {
//            connection = JDBCUtil.getConnection();
//            statement = connection.prepareStatement(sql);
//            statement.setObject(1, id);
//            resultSet = statement.executeQuery();
//            if (resultSet.next()) {
//                obj = aClass.newInstance();// Student student = new Student();
//                //后面都是用反射去获取Student的字段
//                Field[] fields = aClass.getDeclaredFields();
//                for (Field field : fields) {
//                    String fieldName = field.getName();
//                    String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
//                    //通过反射 获取set的方法
//                    Method method = aClass.getDeclaredMethod(methodName, field.getType());
//                    //通过反射 代理执行 本质上就等同于 student.setXXX(resultSet.getObject("XXX"));
//                    method.invoke(obj, resultSet.getObject(fieldName));
//                }
//            }
//
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            JDBCUtil.close(null, statement, connection);
//        }
//        return obj;
//    }
//
//    public void update(T t) {
//        Class<?> aClass = t.getClass();
//        //第一步 通过反射，拿到注解
//        Table table = aClass.getDeclaredAnnotation(Table.class);
//        String tableName = null;
//        if (null != table) {
//            //注解里面的值 就是表名
//            tableName = table.value();
//        }
//        StringBuilder sql = new StringBuilder();
//        sql.append("update ").append(tableName).append(" set id = ?,");
//        Field[] fields = aClass.getDeclaredFields();
//        try {
//            for (Field field : fields) {
//                String fieldName = field.getName();
//                if(!"id".equals(fieldName)){
//                    String methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
//                    //通过反射 获取get的方法
//                    Method method = aClass.getDeclaredMethod(methodName);
//                    Object obj = method.invoke(t);
//                    if(null != obj){
//                        sql.append(fieldName).append(" = ?,");
//                    }
//                }
//            }
//            sql.delete(sql.lastIndexOf(","), sql.length());
//            sql.append(" where id = ? ");
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//        Connection connection = null;
//        PreparedStatement statement = null;
//        try {
//            int count = 0;
//            connection = JDBCUtil.getConnection();
//            statement = connection.prepareStatement(sql.toString());
//            //因为ID 肯定是100%有的，service层会处理
//            Method method = aClass.getDeclaredMethod("getId");
//            Object id = method.invoke(t);
//            statement.setObject(++count, id);
//            for (Field field : fields) {
//                String fieldName = field.getName();
//                if(!"id".equals(fieldName)){
//                    String methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
//                    //通过反射 获取get的方法
//                    Method getMethod = aClass.getDeclaredMethod(methodName);
//                    Object obj = getMethod.invoke(t);
//                    if(null != obj){
//                        statement.setObject(++count, obj);
//                    }
//                }
//            }
//            statement.setObject(++count, id);
//            statement.execute();
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            JDBCUtil.close(null, statement, connection);
//        }
//
//    }
}
